package fr.auzaiphe.admin.view;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SpringLayout;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.table.DefaultTableModel;

import fr.auzaiphe.admin.constantes.ConstantesAdmin;
import fr.auzaiphe.admin.controller.AdminController;
import fr.auzaiphe.admin.model.Joueur;

public class AjoutIndiceFrame extends JFrame
{
	private AdminController controller;

	private ArrayList<String> joueurs;

	private SpringLayout layout;
	private JTabbedPane onglets;
	private JButton buttonValider;

	private JPanel panelJoueur;
	private SpringLayout layoutJoueur;
	private JScrollPane scrollJoueur;
	private DefaultTableModel modelTableauJoueur;
	private JTable tableauJoueur;

	private JPanel panelIndice;
	private SpringLayout layoutIndice;
	private JTextField fieldTitreIndice;
	private JTextArea areaContenuIndice;
	private JScrollPane scrollAreaContenu;
	private JTextField fieldPathIndice;
	private JButton buttonParcourir;

	private JPanel panelTemps;
	private SpringLayout layoutTemps;
	private JLabel labelDebutIndice;
	private JSlider sliderDebutIndice;
	private JLabel labelDebutTemps;

	private JLabel labelFinIndice;
	private JSlider sliderFinIndice;
	private JLabel labelFinTemps;

	private JLabel labelAttention;

	private int dureePartie;

	private int id;



	public AjoutIndiceFrame( AdminController pController,
												  int pDureePartie,
												  ArrayList<String> pJoueurs )
	{
		this.controller = pController;
		this.joueurs = pJoueurs;
		this.dureePartie = pDureePartie;
		this.creerFenetreIndice();
		this.listenerIndiceAdd();
		this.listenerParcourirAdd();
	}

	/**
	 * Affiche une frame via des données
	 * @param pController
	 * @param pDureePartie
	 * @param pJoueurs
	 * @param pId
	 * @param pJoueursVisibles
	 * @param pJoueursLies
	 * @param pTitreIndice
	 * @param pContenuIndice
	 * @param pPathIndice
	 * @param pDebutVie
	 * @param pFinVie
	 * TODO Affichage des listes de joueurs
	 */
	public AjoutIndiceFrame( AdminController pController,
			  int pDureePartie,
			  ArrayList<String> pJoueurs,
			  int pId,
			  ArrayList<Joueur> pJoueursVisibles,
			  ArrayList<Joueur> pJoueursLies,
			  String pTitreIndice,
			  String pContenuIndice,
			  String pPathIndice,
			  int pDebutVie,
			  int pFinVie)
	{
		this.controller = pController;
		this.joueurs = pJoueurs;
		this.dureePartie = pDureePartie;
		this.creerFenetreIndice();
		this.listenerIndiceUpdate(pId);
		this.listenerParcourirAdd();
		this.fieldTitreIndice.setText(pTitreIndice);
		this.areaContenuIndice.setText(pContenuIndice);
		this.fieldPathIndice.setText(pPathIndice);
		this.sliderDebutIndice.setValue(pDebutVie/60);
		this.sliderFinIndice.setValue(pFinVie/60);
		this.setJoueursLies(pJoueursLies);
		this.setJoueursVisibles(pJoueursVisibles);
	}

	private void creerFenetreIndice()
	{

		this.setTitle("Murder Party - Ajouter/Modifier Indice");
		this.setSize(600, 450);
		this.layout = new SpringLayout();
		this.getContentPane().setLayout(this.layout);

		/* Bouton valider :D */
		this.buttonValider = new JButton("Valider");
		this.layout.putConstraint(SpringLayout.SOUTH, this.buttonValider, -10, SpringLayout.SOUTH, this.getContentPane() );
		this.layout.putConstraint(SpringLayout.EAST, this.buttonValider, -10, SpringLayout.EAST, this.getContentPane() );
		this.getContentPane().add(this.buttonValider);

		/* Definition du gestionnaire d'onglets */
		this.onglets = new JTabbedPane(JTabbedPane.TOP);
		this.layout.putConstraint(SpringLayout.NORTH, this.onglets, 10, SpringLayout.NORTH, this.getContentPane() );
		this.layout.putConstraint(SpringLayout.WEST, this.onglets, 10, SpringLayout.WEST, this.getContentPane() );
		this.layout.putConstraint(SpringLayout.SOUTH, this.onglets, -10, SpringLayout.NORTH, this.buttonValider );
		this.layout.putConstraint(SpringLayout.EAST, this.onglets, -10, SpringLayout.EAST, this.getContentPane() );
		this.getContentPane().add(this.onglets);

		/* Onglet Contenu */
		this.panelIndice = new JPanel();
		this.onglets.addTab( "Contenu", this.panelIndice );
		this.layoutIndice = new SpringLayout();
		this.panelIndice.setLayout(this.layoutIndice);

		this.buttonParcourir = new JButton(ConstantesAdmin.BOUTON_CHARGER_MEDIA);
		this.layoutIndice.putConstraint(SpringLayout.EAST, this.buttonParcourir, -10, SpringLayout.EAST, this.panelIndice);
		this.layoutIndice.putConstraint(SpringLayout.SOUTH, this.buttonParcourir, -10, SpringLayout.SOUTH, this.panelIndice);
		this.panelIndice.add(this.buttonParcourir);

		this.fieldTitreIndice = new JTextField("Nouvel Indice");
		this.layoutIndice.putConstraint(SpringLayout.NORTH, this.fieldTitreIndice, 10, SpringLayout.NORTH, this.panelIndice );
		this.layoutIndice.putConstraint(SpringLayout.WEST, this.fieldTitreIndice, 10, SpringLayout.WEST, this.panelIndice);
		this.layoutIndice.putConstraint(SpringLayout.EAST, this.fieldTitreIndice, -10, SpringLayout.EAST, this.panelIndice );
		this.panelIndice.add(this.fieldTitreIndice);

		this.fieldPathIndice = new JTextField();
		this.layoutIndice.putConstraint(SpringLayout.SOUTH, this.fieldPathIndice, 0, SpringLayout.SOUTH, this.buttonParcourir );
		this.layoutIndice.putConstraint(SpringLayout.NORTH, this.fieldPathIndice, 0, SpringLayout.NORTH, this.buttonParcourir );
		this.layoutIndice.putConstraint(SpringLayout.WEST, this.fieldPathIndice, 10, SpringLayout.WEST, this.panelIndice);
		this.layoutIndice.putConstraint(SpringLayout.EAST, this.fieldPathIndice, -10, SpringLayout.WEST, this.buttonParcourir );
		this.panelIndice.add(this.fieldPathIndice);

		this.areaContenuIndice =new JTextArea();
		this.scrollAreaContenu = new JScrollPane( this.areaContenuIndice );
		this.layoutIndice.putConstraint(SpringLayout.NORTH, this.scrollAreaContenu, 10, SpringLayout.SOUTH, this.fieldTitreIndice);
		this.layoutIndice.putConstraint(SpringLayout.WEST, this.scrollAreaContenu, 10, SpringLayout.WEST, this.panelIndice);
		this.layoutIndice.putConstraint(SpringLayout.SOUTH, this.scrollAreaContenu, -10, SpringLayout.NORTH, this.fieldPathIndice);
		this.layoutIndice.putConstraint(SpringLayout.EAST, this.scrollAreaContenu, -10, SpringLayout.EAST, this.panelIndice);
		this.panelIndice.add( this.scrollAreaContenu );

		/* Onglet Joueur */
		this.panelJoueur = new JPanel();
		this.onglets.addTab( "Joueur", this.panelJoueur );
		this.layoutJoueur = new SpringLayout();
		this.panelJoueur.setLayout(this.layoutJoueur);

		this.scrollJoueur = new JScrollPane();
		this.layoutJoueur.putConstraint(SpringLayout.NORTH, this.scrollJoueur, 10, SpringLayout.NORTH, this.panelJoueur );
		this.layoutJoueur.putConstraint(SpringLayout.WEST, this.scrollJoueur, 10, SpringLayout.WEST, this.panelJoueur );
		this.layoutJoueur.putConstraint(SpringLayout.SOUTH, this.scrollJoueur, -10, SpringLayout.SOUTH, this.panelJoueur );
		this.layoutJoueur.putConstraint(SpringLayout.EAST, this.scrollJoueur, -10, SpringLayout.EAST, this.panelJoueur );
		this.panelJoueur.add( this.scrollJoueur );

		this.modelTableauJoueur = new  DefaultTableModel();
		this.modelTableauJoueur.addColumn(ConstantesAdmin.COLONNES_INDICE_DETAIL[0]);
		this.modelTableauJoueur.addColumn(ConstantesAdmin.COLONNES_INDICE_DETAIL[1]);
		this.modelTableauJoueur.addColumn(ConstantesAdmin.COLONNES_INDICE_DETAIL[2]);
		this.modelTableauJoueur.setRowCount(0);
		this.tableauJoueur = new JTable( this.modelTableauJoueur );

		// Permet le rendu en checkbox des booleans dans le tableau
		this.tableauJoueur.getColumnModel().getColumn(1).setCellRenderer( new CellCheckBoxRender() );
		this.tableauJoueur.getColumnModel().getColumn(2).setCellRenderer( new CellCheckBoxRender() );
		this.tableauJoueur.getColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(new JCheckBox()));
		this.tableauJoueur.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(new JCheckBox()));

		for(String j : this.joueurs)
		{
			Object [] data = {j,false,false};
			this.modelTableauJoueur.addRow(data);
		}

		this.scrollJoueur.setViewportView( this.tableauJoueur );

		/* Onglet gestion du temps */
		this.panelTemps = new JPanel();
		this.onglets.addTab("Temps", this.panelTemps);
		this.layoutTemps = new SpringLayout();
		this.panelTemps.setLayout( this.layoutTemps );

		this.labelAttention = new JLabel("Attention, la fin de vie ne doit pas être avant le début de vie", JLabel.CENTER );
		this.panelTemps.add( this.labelAttention );
		this.labelAttention.setVisible(false);

		this.labelDebutIndice = new JLabel("Début de vie de l'indice :" , JLabel.CENTER );
		this.layoutTemps.putConstraint( SpringLayout.NORTH, this.labelDebutIndice, 20, SpringLayout.NORTH, this.panelTemps );
		this.layoutTemps.putConstraint( SpringLayout.WEST, this.labelDebutIndice, 5, SpringLayout.WEST, this.panelTemps );
		this.layoutTemps.putConstraint( SpringLayout.EAST, this.labelDebutIndice, -5, SpringLayout.EAST, this.panelTemps );
		this.panelTemps.add( this.labelDebutIndice );

		this.labelDebutTemps = new JLabel();
		this.layoutTemps.putConstraint(SpringLayout.NORTH, this.labelDebutTemps, 15, SpringLayout.SOUTH, this.labelDebutIndice );
		this.layoutTemps.putConstraint(SpringLayout.EAST, this.labelDebutTemps, -5, SpringLayout.EAST, this.panelTemps );
		this.layoutTemps.putConstraint(SpringLayout.WEST, this.labelDebutTemps, -70, SpringLayout.EAST, this.labelDebutTemps );
		this.panelTemps.add(this.labelDebutTemps);

		// Ordre un peu bizarre mais ça evite les NullPointerException
		this.sliderDebutIndice = new JSlider( 0, this.dureePartie, 0 );
		this.sliderDebutIndice.setMajorTickSpacing( 20 );
		this.sliderDebutIndice.setMinorTickSpacing( 0 );
		this.sliderDebutIndice.setPaintTicks(true);
		this.sliderDebutIndice.addChangeListener( new ChangeListener()
		{
			@Override
			public void stateChanged(ChangeEvent arg0)
			{
				AjoutIndiceFrame.this.labelDebutTemps.setText( AjoutIndiceFrame.this.sliderDebutIndice.getValue() / 60 + "h" +
															   AjoutIndiceFrame.this.sliderDebutIndice.getValue() % 60 );
				if ( AjoutIndiceFrame.this.sliderDebutIndice.getValue() < AjoutIndiceFrame.this.sliderFinIndice.getValue() )
				{
					AjoutIndiceFrame.this.labelAttention.setVisible( true );
				}
				else
				{
					AjoutIndiceFrame.this.labelAttention.setVisible( false );
				}
			}
		});

		this.layoutTemps.putConstraint( SpringLayout.NORTH, this.sliderDebutIndice, 15, SpringLayout.SOUTH, this.labelDebutIndice );
		this.layoutTemps.putConstraint( SpringLayout.WEST, this.sliderDebutIndice, 5, SpringLayout.WEST, this.panelTemps );
		this.layoutTemps.putConstraint( SpringLayout.EAST, this.sliderDebutIndice, -5, SpringLayout.WEST, this.labelDebutTemps );
		this.panelTemps.add( this.sliderDebutIndice );

		this.labelDebutTemps.setText( this.sliderDebutIndice.getValue() / 60 + "h" +
				   					  this.sliderDebutIndice.getValue() % 60  );



		this.labelFinIndice = new JLabel("Fin de vie de l'indice :" , JLabel.CENTER );
		this.labelFinIndice.setAlignmentX( JLabel.CENTER_ALIGNMENT );
		this.layoutTemps.putConstraint( SpringLayout.NORTH, this.labelFinIndice, 40, SpringLayout.NORTH, this.sliderDebutIndice );
		this.layoutTemps.putConstraint( SpringLayout.WEST, this.labelFinIndice, 5, SpringLayout.WEST, this.panelTemps );
		this.layoutTemps.putConstraint( SpringLayout.EAST, this.labelFinIndice, -5, SpringLayout.EAST, this.panelTemps );
		this.panelTemps.add( this.labelFinIndice );

		this.labelFinTemps = new JLabel();
		this.labelFinTemps.setAlignmentX( JLabel.CENTER_ALIGNMENT );
		this.layoutTemps.putConstraint(SpringLayout.NORTH, this.labelFinTemps, 15, SpringLayout.SOUTH, this.labelFinIndice );
		this.layoutTemps.putConstraint(SpringLayout.EAST, this.labelFinTemps, -5, SpringLayout.EAST, this.panelTemps );
		this.layoutTemps.putConstraint(SpringLayout.WEST, this.labelFinTemps, -70, SpringLayout.EAST, this.labelFinTemps );
		this.panelTemps.add(this.labelFinTemps);

		// Ordre un peu bizarre mais ça evite les NullPointerException
		this.sliderFinIndice = new JSlider( 0, this.dureePartie, 0 );
		this.sliderFinIndice.setMajorTickSpacing( 20 );
		this.sliderFinIndice.setMinorTickSpacing( 0 );
		this.sliderFinIndice.setPaintTicks(true);
		this.sliderFinIndice.addChangeListener( new ChangeListener()
		{
			@Override
			public void stateChanged(ChangeEvent arg0)
			{
				AjoutIndiceFrame.this.labelFinTemps.setText( AjoutIndiceFrame.this.sliderFinIndice.getValue() / 60 + "h" +
															 AjoutIndiceFrame.this.sliderFinIndice.getValue() % 60 );
				if ( AjoutIndiceFrame.this.sliderDebutIndice.getValue() < AjoutIndiceFrame.this.sliderFinIndice.getValue() )
				{
					AjoutIndiceFrame.this.labelAttention.setVisible( true );
				}
				else
				{
					AjoutIndiceFrame.this.labelAttention.setVisible( false );
				}
			}
		});

		this.layoutTemps.putConstraint( SpringLayout.NORTH, this.sliderFinIndice, 15, SpringLayout.SOUTH, this.labelFinIndice );
		this.layoutTemps.putConstraint( SpringLayout.WEST, this.sliderFinIndice, 5, SpringLayout.WEST, this.panelTemps );
		this.layoutTemps.putConstraint( SpringLayout.EAST, this.sliderFinIndice, -5, SpringLayout.WEST, this.labelFinTemps );
		this.panelTemps.add( this.sliderFinIndice );

		this.labelFinTemps.setText( this.sliderFinIndice.getValue() / 60 + "h" +
				   					this.sliderFinIndice.getValue() % 60  );

		this.layoutTemps.putConstraint( SpringLayout.NORTH, this.labelAttention, 40, SpringLayout.SOUTH, this.sliderFinIndice );
		this.layoutTemps.putConstraint( SpringLayout.WEST, this.labelAttention, 5, SpringLayout.WEST, this.panelTemps );
		this.layoutTemps.putConstraint( SpringLayout.EAST, this.labelAttention, -5, SpringLayout.EAST, this.panelTemps );
	}


	private void setJoueursLies(ArrayList<Joueur> pJoueursLies)
	{
		String sNomPrenom;
		String[] nomPrenom;
		for(int i = 0; i< pJoueursLies.size(); i++)
		{
			for( int j = 0; j < this.tableauJoueur.getRowCount(); j++ )
			{
				sNomPrenom = (String) this.tableauJoueur.getModel().getValueAt(j, 0);
				nomPrenom = sNomPrenom.split(" ");
				if(nomPrenom[0].equals(pJoueursLies.get(i).getNomPersonnage()) && nomPrenom[1].equals(pJoueursLies.get(i).getPrenomPersonnage()))
				{
					this.tableauJoueur.getModel().setValueAt(true, j, 2);
				}
			}
		}
	}

	private void setJoueursVisibles(ArrayList<Joueur> pJoueursVisibles)
	{
		String sNomPrenom;
		String[] nomPrenom;
		for(int i = 0; i< pJoueursVisibles.size(); i++)
		{
			for( int j = 0; j < this.tableauJoueur.getRowCount(); j++ )
			{
				sNomPrenom = (String) this.tableauJoueur.getModel().getValueAt(j, 0);
				nomPrenom = sNomPrenom.split(" ");
				if(nomPrenom[0].equals(pJoueursVisibles.get(i).getNomPersonnage()) && nomPrenom[1].equals(pJoueursVisibles.get(i).getPrenomPersonnage()))
				{
					this.tableauJoueur.getModel().setValueAt(true, j, 1);
				}
			}
		}
	}

	protected ArrayList<String> getJoueursLies()
	{
		ArrayList<String> joueurLies = new ArrayList<String>();

		for( int i = 0; i < this.tableauJoueur.getRowCount(); i++ )
		{
			if( (Boolean) this.tableauJoueur.getModel().getValueAt( i, 2 ) )
			{
				joueurLies.add( (String) this.tableauJoueur.getModel().getValueAt( i , 0 ) );
			}
		}

		return joueurLies;
	}

	protected ArrayList<String> getJoueursVisibles()
	{
		ArrayList<String> joueurVisibles = new ArrayList<String>();

		for( int i = 0; i < this.tableauJoueur.getRowCount(); i++ )
		{
			if( (Boolean) this.tableauJoueur.getModel().getValueAt( i, 1 ) )
			{
				joueurVisibles.add( (String) this.tableauJoueur.getModel().getValueAt( i , 0 ) );
			}
		}

		return joueurVisibles;
	}

	private void listenerIndiceAdd(){
		this.buttonValider.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent arg0)
			{
				AjoutIndiceFrame.this.controller.addIndice(
					AjoutIndiceFrame.this.getJoueursVisibles(),
					AjoutIndiceFrame.this.getJoueursLies(),
					AjoutIndiceFrame.this.fieldTitreIndice.getText(),
					AjoutIndiceFrame.this.areaContenuIndice.getText(),
					AjoutIndiceFrame.this.fieldPathIndice.getText(),
					AjoutIndiceFrame.this.sliderDebutIndice.getValue()*60,
					AjoutIndiceFrame.this.sliderFinIndice.getValue()*60
				);
				AjoutIndiceFrame.this.dispose();
			}
		});
	}

	private void listenerParcourirAdd(){
		this.buttonParcourir.addActionListener(new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent arg0)
			{
				AjoutIndiceFrame.this.controller.parcourir(AjoutIndiceFrame.this.fieldPathIndice);
			}
		});
	}

	private void listenerIndiceUpdate(int pId) {
		this.setId(pId);
		this.buttonValider.addActionListener( new ActionListener()
		{
			@Override
			public void actionPerformed(ActionEvent arg0)
			{
				AjoutIndiceFrame.this.controller.updateIndice(
					AjoutIndiceFrame.this.getId(),
					AjoutIndiceFrame.this.getJoueursVisibles(),
					AjoutIndiceFrame.this.getJoueursLies(),
					AjoutIndiceFrame.this.fieldTitreIndice.getText(),
					AjoutIndiceFrame.this.areaContenuIndice.getText(),
					AjoutIndiceFrame.this.fieldPathIndice.getText(),
					AjoutIndiceFrame.this.sliderDebutIndice.getValue()*60,
					AjoutIndiceFrame.this.sliderFinIndice.getValue()*60
				);
				AjoutIndiceFrame.this.dispose();
			}
		});
	}

	/**
	 * @return the id
	 */
	public int getId() {
		return this.id;
	}

	/**
	 * @param id the id to set
	 */
	public void setId(int id) {
		this.id = id;
	}
}
